#pragma once

#include <iostream>
#include <string>
#include <algorithm>
#include <sys/wait.h>
#include <unordered_map>
#include <fstab.h>
#include <sstream>
#include <fstream>
#include <vector>
#include <cassert>
#include "../common/Util.hpp"
#include "../common/Log.hpp"


namespace ns_model{
    struct Question{
        
        //具体题目描述在对应question目录下的编号目录，如/question/1/desc.txt
        //为什么题号不直接用纯数字，因为题号可以是A1
        std::string _number;
        std::string _title;
        std::string _degreeOfDifficult;

        /*秒级CPU限制*/
        int64_t _CPU_limit;

        /*KB,内存限制*/
        int64_t _Memory_limit;

        std::string _desc;

        //预设给用户的代码，当需要接口就填写在这里
        std::string _header_cpp;

        //主代码，如果直接是接口是代码，该文件里需要有main，如果是直接输入形，那么main_cpp就不需要有内容
        std::string _main_cpp;
    };
    const std::string &questionDIr = "./question/";
    const std::string &question_list = "./question/question.list";
    const std::string &descFilename = "desc.txt";
    const std::string & header_cpp = "header.cpp";
    const std::string& main_cpp = "main.cpp";
    class Model{
        private:
        std::unordered_map<std::string,Question> _questions;
        public:
        Model(const std::string &questionList = question_list)
        {
            assert(LoadQuestionList(questionList));
        }
        bool LoadQuestionList(const std::string &questionList)
        {
            std::ifstream file(questionList);
            if (!file.is_open()) {
                std::cerr << ns_Log::lg(ns_Log::Fatal,__FILE__,__LINE__);
                std::cerr << "无法题目列表文件: " << questionList << std::endl;
                return 0;
            }

            std::string line;
            std::getline(file,line);//读取标题行
            while (std::getline(file, line)) {
                std::vector<std::string> SepRes = ns_Util::StringUtil::SepString(line," \t\n");
                Question q;
                if(SepRes.size()!= 5)
                {
                    std::cerr<<ns_Log::lg(ns_Log::Fatal,__FILE__,__LINE__)<<"文件格式读取出错，请检查文件格式。\n";
                    std::cerr<<"目前读取的文件格式序号是 ："<<q._number<<"\n";
                }
                q._number = SepRes[0];
                q._title = SepRes[1];
                q._degreeOfDifficult = SepRes[2];
                q._CPU_limit = std::stoll(SepRes[3]);
                q._Memory_limit=  std::stoll(SepRes[4]);

                q._desc  = ns_Util::FileUtil::ReadFileToString(questionDIr + q._number + "/" + descFilename);
                q._header_cpp = ns_Util::FileUtil::ReadFileToString(questionDIr + q._number + "/" + header_cpp);
                q._main_cpp = ns_Util::FileUtil::ReadFileToString(questionDIr +q._number + "/" + main_cpp);
                _questions[q._number] = q; 
            }
            file.close();
            return 1;
        }
        bool GetAllQuestions(std::vector<Question> *out)
        {
            if(_questions.size()==0)
            {
                std::cerr<<ns_Log::lg(ns_Log::Fatal,__FILE__,__LINE__)<<"获取所有题目失败\n";
                return false;
            }
            for(const auto& q:_questions)
            {
                out->push_back(q.second);
            }
            //解决题号混乱问题，排序
            std::sort(out->begin(),out->end(),[](const Question& a,const Question& b){
                return a._number < b._number;
            }
            );
            return 1;
        }
        bool GetOneQuestion(const std::string& number,Question*q)
        {
            if(_questions.find(number) == _questions.end())
            {
                std::cerr<<ns_Log::lg(ns_Log::Fatal,__FILE__,__LINE__)<<"获取:"<<number<<"号题目失败\n";
                return 0;
            }
            (*q) = _questions[number];
            return 1;
        }
    };
};
